package com.ttt.map;

import com.ttt.game.GameFrame;
import com.ttt.game.LevelInof;
import com.ttt.tank.Tank;
import com.ttt.util.Constant;
import com.ttt.util.MapWallPool;

import java.awt.*;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * 游戏地图类
 */
public class GameMap {

    //static定义为常量，死的,前两个是左上角坐标，后两个是宽高
    private static final int Map_x = Tank.Radius * 3;
    private static final int Map_y = Tank.Radius * 3 + GameFrame.titleBraH;
    private static final int Map_Width = Constant.Frame_Width - Tank.Radius * 6;
    private static final int Map_Height = Constant.Frame_Height - Tank.Radius * 8 - GameFrame.titleBraH;

    //游戏地图元素块的容器
    private List<MapWall> walls = new ArrayList<>();

    //大本营
    private TankHouse house;

    public GameMap() { }

    /**
     * 初始化地图元素块,level:地图第几关
     */
    public void initMap(int level){
        walls.clear();
        try {
            loadlevel(level);
        }catch (Exception e){
            e.printStackTrace();
        }
//        //随机的得到一个地图元素块，添加到容器中
//        final int Count = 50;
//        for (int i = 0; i < Count; i++) {
//            MapWall wall = MapWallPool.get();
//            int x = MyUtil.getRandomNumber(Map_x,Map_x + Map_Width - MapWall.wallW);
//            int y = MyUtil.getRandomNumber(Map_y,Map_y + Map_Height - MapWall.wallH);
//            //新生成的随机块和已经存在的块有重叠的部分，那就重新生成
//            if (isCollide(walls,x,y)){
//                i--;
//                continue;
//            }
//            wall.setX(x);
//            wall.setY(y);
//            walls.add(wall);
//        }
        //三行的一个地图
//        addRow(Map_x,Map_y,Map_x + Map_Width,MapWall.Type_Normal,0);
//        addRow(Map_x,Map_y + MapWall.wallW * 3,Map_x + Map_Width,MapWall.Type_Cover,0);
//        addRow(Map_x,Map_y + MapWall.wallW * 6,Map_x + Map_Width,MapWall.Type_Hard,MapWall.wallW+10);

        //初始化大本营
        house = new TankHouse();
        addHouse();
    }

    /**
     * 加载关卡信息
     * @param level
     */
    private void loadlevel(int level) throws Exception {
        //获得关卡信息类的唯一实例对象
        LevelInof levelInof = LevelInof.getInstance();
        //设置关卡
        levelInof.setLevel(level);
        Properties prop = new Properties();
        prop.load(new FileInputStream("level/lv_"+level));
        //将所有的地图信息加载进来
        int enemyCount = Integer.parseInt(prop.getProperty("enemyCount"));
        //设置敌人数量
        levelInof.setEnemyCount(enemyCount);
        //0,1 对敌人类型解析
        String[] enemyType = prop.getProperty("enemyType").split(",");
        int[] type = new int[enemyType.length];
        for (int i = 0; i < type.length; i++) {
            type[i] = Integer.parseInt(enemyType[i]);
        }
        //设置敌人类型
        levelInof.setEnemyType(type);
        //关卡难度
        //如果没有设计游戏难度，游戏难度默认1
        String levelType = prop.getProperty("levelType");
        levelInof.setLevelType(Integer.parseInt(levelType == null ? "1" : levelType));
        String methodName = prop.getProperty("method");
        int invokeCount = Integer.parseInt(prop.getProperty("invokeCount"));
        //把实参都读取到数组中来
        String[] params = new String[invokeCount];
        for (int i = 1; i <= invokeCount; i++) {
            params[i - 1] = prop.getProperty("param" + i);
        }
//        System.out.println(enemyCount);
//        System.out.println(methodName);
//        System.out.println(params[0]);
//        System.out.println(params[1]);
        //使用读取到的参数，调用对应的方法
        invokeMethod(methodName,params);
    }
    //根据方法的名字和参数调用对应的方法
    private void invokeMethod(String name,String[] params){
        for (String param : params){
            //获得每一行方法的参数，解析。
            String[] split = param.split(",");
            //使用一个int数组保存解析后的内容
            int[] arr = new int[split.length];
            int i;
            for (i = 0; i < split.length - 1; i++) {
                arr[i] = Integer.parseInt(split[i]);
            }
            //块之间的间隔是地图块的倍数
            final int DIS = MapWall.wallW;

            //解析最后一个double值
            int dis = (int) (Double.parseDouble(split[i])*DIS);
            switch (name){
                case "addRow":
                    addRow(Map_x+arr[0]*DIS,Map_y+arr[1]*DIS,
                            Map_x+Map_Width-arr[2]*DIS,arr[3],arr[4]*DIS);
                    break;
                case "addCol":
                    addCol(Map_x+arr[0]*DIS,Map_y+arr[1]*DIS,
                            Map_y+Map_Height-arr[2]*DIS,arr[3],dis);
                    break;
                case "addRect":
                    addRect(Map_x+arr[0]*DIS,Map_y+arr[1]*DIS,
                            Map_x+Map_Width-arr[2]*DIS,
                            Map_y+Map_Height-arr[3]*DIS,arr[4],dis);
                    break;
            }
        }
    }

    //将老巢的所有的元素块添加到地图的容器中来
    private void addHouse(){
        walls.addAll(house.getWalls());
    }

    /**
     * 判断某一个点确定的块是否和walls集合中的所有块有重叠部分
     * @param walls
     * @param x
     * @param y
     * @return 有重叠返回true，否则false
     */
    private boolean isCollide(List<MapWall> walls,int x,int y){
        for (MapWall wall : walls) {
            int wallX = wall.getX();
            int wallY = wall.getY();
            if (Math.abs(wallX - x) < MapWall.wallW && Math.abs(wallY - y) < MapWall.wallW){
                return true;
            }
        }
        return false;
    }

    /**
     * 只对没有遮挡效果的块进行绘制
     * @param g
     */
    public void drawBk(Graphics g){
        for (MapWall wall : walls) {
            if (wall.getType() != MapWall.Type_Cover)
                wall.draw(g);
//            house.draw(g); 已经添加到地图容器中，所以无需绘制
        }
    }

    /**
     * 只绘制有遮挡效果的块
     * @param g
     */
    public void drawCover(Graphics g){
        for (MapWall wall : walls) {
            if (wall.getType() == MapWall.Type_Cover)
            wall.draw(g);
        }
    }

    public List<MapWall> getWalls() {
        return walls;
    }

    /**
     * 将所有的不可见的地图块从容器中移除
     */
    public void clearDestoryWall(){
        for (int i = 0; i < walls.size(); i++) {
            MapWall wall = walls.get(i);
            if (!wall.isVisible())
                walls.remove(i);
        }
    }

    /**
     * 往地图块容器中添加一行指定类型的地图块
     * @param startX 添加地图快的起始的x坐标
     * @param startY 添加地图快的起始的y坐标
     * @param endX 添加地图快的结束的x坐标
     * @param type 地图块的类型
//     * @param isLinked true，代表地图块是连续的，false意味着地图块存在间隔
     * @param DIS 地图块之间的中心点的间隔 如果是块的宽度 意味着是连续的，
     *            如果大于块的宽度就是不连续的
     */
    public void addRow(int startX,int startY,int endX,int type,final int DIS){
        int count = (endX - startX)/(MapWall.wallW + DIS);
        for (int i = 0; i < count; i++) {
            MapWall wall = MapWallPool.get();
            wall.setType(type);
            wall.setX(startX + i * (MapWall.wallW + DIS));
            wall.setY(startY);
            walls.add(wall);
        }
    }

    /**
     * 地图块容器中添加一列指定类型的地图块
     * @param startX 该列的起始x坐标
     * @param startY 该列的起始y坐标
     * @param endY 该列的结束y坐标
     * @param type 地图块的类型
     * @param DIS 地图块之间的中心点的间隔
     */
    public void addCol(int startX,int startY,int endY,int type,final int DIS){
        int count = (endY - startY)/(MapWall.wallW + DIS);
        for (int i = 0; i < count; i++) {
            MapWall wall = MapWallPool.get();
            wall.setType(type);
            wall.setX(startX);
            wall.setY(startY + i * (MapWall.wallW + DIS));
            walls.add(wall);
        }
    }

    /**
     * 对指定的矩形区域添加地图块
     * @param startX
     * @param startY
     * @param endX
     * @param endY
     * @param type
     * @param DIS
     */
    public void addRect(int startX,int startY,int endX,int endY,int type,final int DIS){
        int rows = (endY - startY)/(MapWall.wallW + DIS);

        for (int i = 0; i < rows; i++) {
            addRow(startX,startY + i * (MapWall.wallW + DIS),endX,type,DIS);
        }

//        int cols = (endX - startX)/(MapWall.wallW + DIS);
    }

}
